package com.kzw.config;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.servlet.MultipartConfigElement;
import javax.sql.DataSource;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;

import org.apache.commons.dbutils.QueryRunner;
import org.hibernate.SessionFactory;
import org.hibernate.validator.HibernateValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.AdviceMode;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.support.OpenSessionInViewFilter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.context.request.RequestContextListener;

import com.kzw.misc.utils.AppUtil;

@Configuration
@EnableTransactionManagement(mode = AdviceMode.PROXY)
public class AppConfig {
	
	@Autowired
	private DataSource dataSource;

	@Bean
	public QueryRunner queryRunner() {
		DataSource proxy = new TransactionAwareDataSourceProxy(dataSource);
		return new QueryRunner(proxy);
	}

	@Bean
	public Validator validator() {
		ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class).configure()
				.addProperty("hibernate.validator.fail_fast", "true").buildValidatorFactory();
		return validatorFactory.getValidator();
	}

	@Primary
	@Bean
	public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
		return entityManagerFactory(builder).getObject().createEntityManager();
	}

	@Primary
	@Bean
	public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder) {
		return builder.dataSource(dataSource).packages("com.kzw.**.model") // 设置实体类所在位置
				.persistenceUnit("primaryPersistenceUnit").build();
	}

	@Bean
	public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
		return new HibernateTransactionManager(sessionFactory(emf));
	}

	@Bean
	public SessionFactory sessionFactory(EntityManagerFactory emf) {
		return emf.unwrap(SessionFactory.class);
	}
	
	/**
	  *  解决OpenSessionInView问题 
	 * */
	@Bean
	public OpenSessionInViewFilter openSessionInViewFilter(){
	   return new OpenSessionInViewFilter();
	}

	@Bean
	public RequestContextListener requestContextListener() {
		return new RequestContextListener();
	}
	
	@Bean
	public AppUtil appUtil() {
		return new AppUtil();
	}
	
	/** 
     * 文件上传配置 
     * @return MultipartConfigElement 
     */  
    @Bean  
    public MultipartConfigElement multipartConfigElement(  
            @Value("${multipart.maxFileSize}") String maxFileSize,  
            @Value("${multipart.maxRequestSize}") String maxRequestSize) {  
        MultipartConfigFactory factory = new MultipartConfigFactory();  
        factory.setMaxFileSize(maxFileSize);  
        factory.setMaxRequestSize(maxRequestSize);  
        return factory.createMultipartConfig();  
    }

}
